import sys
import traceback
from datetime import datetime

import requests
from PyQt5.QtCore import QTimer, pyqtSignal
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton,
                             QStackedLayout, QHBoxLayout, QTextEdit, QTableWidget, QLabel, QSpinBox, QGroupBox,
                             QDialogButtonBox, QDialog)

from book_view import BookView
from chapter_detail_view import ChapterDetailView
from chapter_view import ChapterView
from novel_splitter_view import NovelSplitterView
from style_manager import StyleManager  # 添加到文件顶部


class SettingsDialog(QDialog):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.setWindowTitle("系统设置")
        self.setModal(True)
        self.parent = parent

        # 应用主题样式
        theme = self.parent.themes[self.parent.current_theme]
        self.setStyleSheet(f"""
            QDialog {{
                background-color: {theme['background']};
                color: {theme['text']};
            }}
            QGroupBox {{
                color: {theme['text']};
                font-size: 14px;
                margin-top: 10px;
                padding: 10px;
            }}
            QLabel {{
                color: {theme['text']};
                min-width: 60px;
            }}
            QSpinBox {{
                color: {theme['text']};
                background-color: {theme['button']};
                min-width: 80px;
            }}
        """)

        # 主布局 - 添加边距和间距
        layout = QVBoxLayout()
        layout.setContentsMargins(15, 15, 15, 15)
        layout.setSpacing(15)

        # 默认字体大小设置
        default_font_group = QGroupBox("默认字体大小")
        default_font_layout = QHBoxLayout()
        default_font_layout.setContentsMargins(10, 10, 10, 10)
        default_font_layout.setSpacing(15)

        self.default_font_spin = QSpinBox()
        self.default_font_spin.setRange(8, 24)
        self.default_font_spin.setValue(self.parent.default_font_size)

        default_font_layout.addWidget(QLabel("大小:"))
        default_font_layout.addWidget(self.default_font_spin)
        default_font_layout.addStretch()
        default_font_group.setLayout(default_font_layout)

        # 内容区域字体大小设置
        content_font_group = QGroupBox("内容区域字体大小")
        content_font_layout = QHBoxLayout()
        content_font_layout.setContentsMargins(10, 10, 10, 10)
        content_font_layout.setSpacing(15)

        self.content_font_spin = QSpinBox()
        self.content_font_spin.setRange(10, 32)
        self.content_font_spin.setValue(self.parent.content_font_size)

        content_font_layout.addWidget(QLabel("大小:"))
        content_font_layout.addWidget(self.content_font_spin)
        content_font_layout.addStretch()
        content_font_group.setLayout(content_font_layout)

        # 按钮
        button_box = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
        button_box.accepted.connect(self.accept)
        button_box.rejected.connect(self.reject)

        layout.addWidget(default_font_group)
        layout.addWidget(content_font_group)
        layout.addStretch()
        layout.addWidget(button_box)
        self.setLayout(layout)

        # 设置对话框最小尺寸
        self.setMinimumSize(400, 300)


# 在MainWindow类中添加分集器视图
class MainWindow(QWidget):
    # 定义信号
    resized = pyqtSignal()

    # 移除类常量定义
    # DEFAULT_FONT_SIZE = 16  # 默认字体大小
    # CONTENT_FONT_SIZE = 20  # 内容区域字体大小
    DEFAULT_COLUMN_WIDTHS = {
        'book': [100, 100, 600, 500, 200],
        'chapter': [200, 200, 500, 200, 200, 200]
    }
    book_id = None

    # 定义窗口默认大小
    DEFAULT_WINDOW_WIDTH = 1280
    DEFAULT_WINDOW_HEIGHT = 800

    def __init__(self):
        super().__init__()
        self.setWindowTitle("带UI的桌面APP")

        # 添加实例属性
        self.default_font_size = 16  # 默认字体大小
        self.content_font_size = 20  # 内容区域字体大小

        # 设置默认窗口大小
        self.setMinimumSize(800, 600)  # 设置最小尺寸
        self.resize(self.DEFAULT_WINDOW_WIDTH, self.DEFAULT_WINDOW_HEIGHT)

        self.showMaximized()

        # 添加共享的log_box属性
        self.log_box = QTextEdit()
        self.log_box.setReadOnly(True)

        # 定义主题
        self.themes = {
            "light": {  # 浅色主题
                "background": "#F8F8FF",  # 主窗口背景色
                "text": "#000000",        # 主要文本颜色+日志框文本颜色
                "button": "#008B8B",      # 按钮背景色（菜单按钮+表头）
                "table": "white",         # 表格背景色(白色)
                "log": "#f0f0f0"          # 日志框背景色(浅灰色)
            },
            "dark": {   # 深色主题
                "background": "#2d2d2d",  # 主窗口背景色(深灰色)
                "text": "#ffffff",        # 主要文本颜色(纯白色)
                "button": "#DAA520",      # 按钮背景色(中灰色)
                "table": "#1e1e1e",       # 表格背景色(接近黑色)
                "log": "#f0f0f0"          # 日志框背景色(浅灰色)
            },
            "eye_care": {  # 护眼主题
                "background": "#e8f4ea",  # 主窗口背景色(淡绿色)
                "text": "black",        # 主要文本颜色(中灰色)
                "button": "#d4e8d4",      # 按钮背景色(浅绿色)
                "table": "#f0f7f0",       # 表格背景色(极淡绿色)
                "log": "#e0eee0"          # 日志框背景色(淡绿色)
            }
        }
        self.current_theme = "dark"  # 将默认主题改为dark

        self.init_ui()
        self.init_data()

    def init_ui(self):
        """初始化UI组件"""
        # 主垂直布局
        main_vlayout = QVBoxLayout(self)
        main_vlayout.setContentsMargins(0, 0, 0, 0)
        main_vlayout.setSpacing(0)

        # 顶部菜单栏
        self.setup_menu_bar(main_vlayout)

        # 创建堆栈布局
        self.stacked_layout = QStackedLayout()
        main_vlayout.addLayout(self.stacked_layout)

        # 添加全局日志框
        self.log_box = QTextEdit()
        self.log_box.setReadOnly(True)
        self.log_box.setMaximumHeight(int(self.height() * 0.15))
        self.log_box.setVisible(True)  # 恢复显示日志框
        main_vlayout.addWidget(self.log_box)

        # 初始化视图
        self.book_view = BookView(self)
        self.chapter_view = ChapterView(self)
        self.chapter_detail_view = ChapterDetailView(self)

        # 添加到堆栈
        self.stacked_layout.addWidget(self.book_view)
        self.stacked_layout.addWidget(self.chapter_view)
        self.stacked_layout.addWidget(self.chapter_detail_view)

        # 添加分集器视图
        self.novel_splitter_view = NovelSplitterView(self)
        self.stacked_layout.addWidget(self.novel_splitter_view)

        # 应用初始主题
        self.apply_theme()

    def init_data(self):
        """初始化数据"""
        # 延迟初始化
        QTimer.singleShot(200, self.fetch_data)
        self.book_view.log_message("日志系统已初始化", 'INFO')

    def setup_menu_bar(self, parent_layout):
        """设置菜单栏"""
        menu_bar = QHBoxLayout()
        menu_bar.setContentsMargins(10, 10, 10, 10)
        menu_bar.setSpacing(15)

        # 菜单按钮
        menu_buttons = [
            ("首页", lambda: self.switch_view(0)),
            ("书籍管理", lambda: self.switch_view(0)),
            ("章节管理", lambda: self.switch_view(1)),
            ("分集器", lambda: self.switch_view(3)),  # 新增分集器
            ("系统设置", self.show_settings)  # 修改为调用show_settings
        ]

        for text, callback in menu_buttons:
            btn = self.create_button(text, callback)
            menu_bar.addWidget(btn)

        # 主题按钮
        theme_btn = self.create_button("主题", self.toggle_theme)
        menu_bar.addWidget(theme_btn)

        menu_bar.addStretch()

        # 添加窗口控制按钮
        minimize_btn = self.create_button("最小化", self.showMinimized)
        window_btn = self.create_button("窗口化", self.toggle_window_state)
        close_btn = self.create_button("关闭", self.close)

        # 设置按钮样式
        minimize_btn.setStyleSheet("padding: 8px 15px; font-size: 14px; background-color: #4a86e8; color: white;")
        window_btn.setStyleSheet("padding: 8px 15px; font-size: 14px; background-color: #2ecc71; color: white;")
        close_btn.setStyleSheet("padding: 8px 15px; font-size: 14px; background-color: #e74c3c; color: white;")

        menu_bar.addWidget(minimize_btn)
        menu_bar.addWidget(window_btn)
        menu_bar.addWidget(close_btn)
        parent_layout.addLayout(menu_bar)

    def create_button(self, text, callback, is_edit=False):
        """创建统一风格的按钮"""
        btn = QPushButton(text)
        if is_edit:
            btn.setStyleSheet("padding: 3px;")
        else:
            btn.setStyleSheet("padding: 8px 15px; font-size: 14px;")
        btn.clicked.connect(callback)
        return btn

    def switch_view(self, index):
        """切换视图"""
        self.book_view.log_message(f"切换到视图 {index}", 'INFO')
        self.stacked_layout.setCurrentIndex(index)

    def fetch_data(self, page=1, page_size=10):
        """获取书籍数据"""
        try:
            payload = {"page": page, "page_size": page_size}
            headers = {"Content-Type": "application/json"}
            response = requests.post("http://127.0.0.1:5000/describeBookList",
                                     json=payload, headers=headers)
            data = response.json()
            self.book_view.setup_table(data)
            self.book_view.log_message("数据加载完成", 'INFO')
        except Exception as e:
            self.book_view.log_message(f"数据加载失败: {str(e)}", 'ERROR')

    def fetch_chapter_data(self, book_id, page=1, page_size=10):
        self.show_chapter_list(book_id, page, page_size)

    def show_chapter_list(self, book_id, page=1, page_size=10):
        self.book_id = book_id
        """显示章节列表"""
        try:
            self.book_view.log_message(f"=== 开始获取书本ID {book_id} 的章节列表 ===", 'INFO')
            payload = {
                "page": page,
                "page_size": page_size,
                "book_id": str(book_id),
            }
            headers = {"Content-Type": "application/json"}

            response = requests.post(f"http://127.0.0.1:5000/describeChapters",
                                     json=payload,
                                     headers=headers,
                                     timeout=5)

            if response.status_code != 200:
                raise Exception(f"接口返回错误: {response.text}")

            chapter_data = response.json()
            self.chapter_view.setup_table(chapter_data)
            self.switch_view(1)

        except Exception as e:
            error_msg = f"ERROR: 获取章节列表失败: {str(e)}\n{traceback.format_exc()}"
            self.book_view.log_message(error_msg, 'ERROR')

    def show_chapter_detail(self, chapter_id):
        """显示章节详情"""
        try:
            self.book_view.log_message(f"=== 开始获取章节ID {chapter_id} 的详情 ===", 'INFO')
            payload = {"chapter_id": chapter_id}
            response = requests.post(f"http://127.0.0.1:5000/describeChapter",
                                     json=payload,
                                     headers={"Content-Type": "application/json"},
                                     timeout=5)

            if response.status_code != 200:
                raise Exception(f"接口返回错误: {response.text}")

            chapter_data = response.json()
            self.chapter_detail_view.setup_view(chapter_data)
            self.switch_view(2)

        except Exception as e:
            error_msg = f"ERROR: 获取章节详情失败: {str(e)}\n{traceback.format_exc()}"
            self.book_view.log_message(error_msg, 'ERROR')

    def toggle_theme(self):
        """切换主题"""
        themes = list(self.themes.keys())
        current_index = themes.index(self.current_theme)
        next_index = (current_index + 1) % len(themes)
        self.current_theme = themes[next_index]
        self.apply_theme()

    def apply_theme(self):
        """应用当前主题"""
        theme = StyleManager.get_theme(self.current_theme)
        self.setStyleSheet(StyleManager.get_style("main_window", self.current_theme))

        # 更新所有视图样式
        for i in range(self.stacked_layout.count()):
            widget = self.stacked_layout.widget(i)
            if hasattr(widget, 'apply_theme'):
                widget.apply_theme()

        # 更新组件样式
        self.update_component_styles()

    def update_component_styles(self):
        """更新所有组件样式"""
        # 更新按钮样式
        for btn in self.findChildren(QPushButton):
            if btn.text() in ["最小化", "窗口化", "关闭"]:
                continue  # 特殊按钮保持原样式
            btn.setStyleSheet(StyleManager.get_style("button", self.current_theme))

        # 更新表格样式
        for table in self.findChildren(QTableWidget):
            table.setStyleSheet(StyleManager.get_style("table", self.current_theme))

        # 更新标签样式
        for label in self.findChildren(QLabel):
            label.setStyleSheet(f"color: {StyleManager.get_theme(self.current_theme)['text']};")

        # 强制刷新UI
        self.style().unpolish(self)
        self.style().polish(self)
        self.update()

    def toggle_window_state(self):
        """切换窗口最大化/窗口化状态"""
        if self.isMaximized():
            self.showNormal()
            # 确保窗口大小合适
            self.resize(self.DEFAULT_WINDOW_WIDTH, self.DEFAULT_WINDOW_HEIGHT)
            # 居中显示窗口
            self.center_window()
            # 更新按钮文本
            for btn in self.findChildren(QPushButton):
                if btn.text() == "窗口化":
                    btn.setText("最大化")
                    break
        else:
            self.showMaximized()
            # 更新按钮文本
            for btn in self.findChildren(QPushButton):
                if btn.text() == "最大化":
                    btn.setText("窗口化")
                    break

        # 记录状态变化
        state = "窗口化" if not self.isMaximized() else "最大化"
        self.book_view.log_message(f"切换到{state}模式 - 窗口大小: {self.width()}x{self.height()}", 'INFO')

    def center_window(self):
        """将窗口居中显示在屏幕上"""
        from PyQt5.QtWidgets import QDesktopWidget
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def log_message(self, message, level="INFO"):
        """统一日志记录方法

        Args:
            message: 日志消息
            level: 日志级别(DEBUG/INFO/WARNING/ERROR)
        """
        if hasattr(self, 'log_box') and self.log_box:
            timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")

            # 使用当前主题的文本颜色，而不是固定颜色
            theme_color = self.themes[self.current_theme]['text']
            color = {
                "DEBUG": "orange",
                "INFO": theme_color,
                "WARNING": "orange",
                "ERROR": "red"
            }.get(level.upper(), theme_color)

            # 格式化日志消息
            log_entry = f"[{timestamp}] [{level}] {message}"

            # 使用HTML格式设置颜色
            self.log_box.append(f"<span style='color:{color}'>{log_entry}</span>")

            # 自动滚动到底部
            self.log_box.verticalScrollBar().setValue(
                self.log_box.verticalScrollBar().maximum()
            )

    def resizeEvent(self, event):
        """重写resizeEvent以在窗口大小变化时发出信号"""
        super().resizeEvent(event)
        self.resized.emit()

    def show_settings(self):
        """显示系统设置对话框"""
        dialog = SettingsDialog(self)
        if dialog.exec_() == QDialog.Accepted:
            # 保存设置
            self.default_font_size = dialog.default_font_spin.value()
            self.content_font_size = dialog.content_font_spin.value()

            # 应用新设置
            self.apply_font_settings()
            self.log_message("字体设置已更新", "INFO")

    def apply_font_settings(self):
        """应用字体设置到所有视图"""
        # 更新表格字体
        for table in self.findChildren(QTableWidget):
            font = table.font()
            font.setPointSize(self.default_font_size)
            table.setFont(font)

            header_font = table.horizontalHeader().font()
            header_font.setPointSize(self.default_font_size)
            table.horizontalHeader().setFont(header_font)

        # 更新内容区域字体（仅在视图存在时）
        if hasattr(self, 'chapter_detail_view') and self.chapter_detail_view and \
           hasattr(self.chapter_detail_view, 'content_view') and self.chapter_detail_view.content_view:
            self.chapter_detail_view.content_view.setStyleSheet(
                f"font-size: {self.content_font_size}px;"
            )

        # 更新日志框字体
        if hasattr(self, 'log_box') and self.log_box:
            self.log_box.setStyleSheet(
                f"font-size: {self.default_font_size}px;"
            )


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec_())